package com.example.myapp.event;

import java.lang.ref.WeakReference;
import java.util.*;

public class EventHandler {

    private static HashMap<Class, Set<WeakReference<Object>>> listeners = new HashMap<>();


    public static void register(EventListener listener, Class eventType) {
        if (listeners.get(eventType) == null) {
            listeners.put(eventType, new HashSet<>());
        }

        listeners.get(eventType).add(new WeakReference<>(listener));
    }

    public static void handleEvent(EventObject event) {
        Set<WeakReference<Object>> specListeners = listeners.get(event.getClass());
        if (specListeners != null && specListeners.size() > 0) {
            if (event.getClass() == ClickOnCellEvent.class) {
                for (WeakReference<Object> reference : specListeners) {
                    Object listener = reference.get();
                    if (listener != null) {
                        ((ClickOnCellEventListener) listener).clickOnCellEvent((ClickOnCellEvent) event);
                    } else {
                        specListeners.remove(reference);
                    }
                }
            } else if (event.getClass() == StateMatrixChangeEvent.class) {
                for (WeakReference<Object> reference : specListeners) {
                    Object listener = reference.get();
                    if (listener != null) {
                        ((StateMatrixChangeEventListener) listener).stateMatrixOnChange((StateMatrixChangeEvent) event);
                    } else {
                        specListeners.remove(reference);
                    }
                }
            } else if (event.getClass() == RequestRenderEvent.class) {
                for (WeakReference<Object> reference : specListeners) {
                    Object listener = reference.get();
                    if (listener != null) {
                        ((RequestRenderEventListener) listener).onRequestRender((RequestRenderEvent) event);
                    } else {
                        specListeners.remove(reference);
                    }
                }
            } else if (event.getClass() == GameEndEvent.class) {
                for (WeakReference<Object> reference : specListeners) {
                    Object listener = reference.get();
                    if (listener != null) {
                        ((GameEndEventListener) listener).onGameEnd((GameEndEvent) event);
                    } else {
                        specListeners.remove(reference);
                    }
                }
            }
        }
    }

//    public static void fireDefaultEvent(Class<EventObject> eventClass, Object trigger) {
//        try {
//            Constructor<EventObject> constructor = eventClass.getConstructor(eventClass, Object.class);
//            EventObject eventObject = constructor.newInstance(trigger);
//            handleEvent(eventObject);
//        } catch (NoSuchMethodException | InvocationTargetException | InstantiationException | IllegalAccessException e) {
//            e.printStackTrace();
//        }
//    }
}
